package com.lanyun.controller;

import cn.org.atool.fluent.mybatis.If;
import cn.org.atool.fluent.mybatis.model.StdPagedList;
import com.lanyun.common.GA;
import com.lanyun.common.R;
import com.lanyun.dao.intf.ScenicDao;
import com.lanyun.entity.ScenicEntity;
import com.lanyun.entity.vo.MapQuery;
import com.lanyun.entity.vo.ScenicQueryPage;
import com.lanyun.mapper.ScenicMapper;
import com.lanyun.util.DistanceUtil;
import com.lanyun.wrapper.ScenicQuery;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description: TODO
 * @author: LanYun
 * @date: 2022/2/22 19:16
 * @Version: 1.0
 */
@Api()
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/scenic")
public class ScenicController {
    @Autowired
    private ScenicDao scenicDao;
    @Resource
    private ScenicMapper scenicMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * @Description 根据id查找景点
     * @Param id:
     * @Author LanYun
     * @Date 2022/2/27 15:54
     */
    @GetMapping("/{id}")
    public R getId(@PathVariable("id") Long id) {
        ScenicEntity byId = scenicMapper.findById(id);
        return R.ok().data("scenic", byId);
    }

    /**
     * @Description 保存景点
     * @Param scenicEntity:
     * @Author LanYun
     * @Date 2022/2/27 16:11
     */
    @PostMapping("/save")
    public R save(@RequestBody ScenicEntity scenicEntity) {
//        ScenicQuery end = new ScenicQuery().select.max.imageId().end();
//        List<Integer> objects = scenicMapper.listObjs(end);
//        Integer o = objects.get(0);
//        scenicEntity.setImageId(o+1);
        System.out.println(scenicEntity);
        scenicMapper.save(scenicEntity);
        return R.ok();
    }

    /**
     * @Description 景点分页
     * @Param current:
     * @Param limit:
     * @Author LanYun
     * @Date 2022/2/27 15:54
     */
    @PostMapping("/scenicPage/{current}/{limit}")
    public R scenicList(@PathVariable int current, @PathVariable int limit, @RequestBody(required = false) ScenicQueryPage scenicQueryPage) {
        //1 构建查询对象
        ScenicQuery scenicQuery = new ScenicQuery();
        //2 景点名不为空，添加查询名字条件
        if (If.notNull(scenicQueryPage.getName())) {
            scenicQuery.where().name().like(scenicQueryPage.getName());
        }
        //3 景点类型不为空，添加查询类型条件
        if (If.notNull(scenicQueryPage.getScenicType())) {
            scenicQuery.where().scenicType().eq(scenicQueryPage.getScenicType());
        }
        //4 只查询未删除的
        scenicQuery.where.isDeleted().eq(0);
        //5 设置分页
        scenicQuery.limit((current - 1) * limit, limit);
        //6 到数据查询以上条件构造出来的查询对象
        StdPagedList<ScenicEntity> list = scenicMapper.stdPagedEntity(scenicQuery);
        //7 返回查询结果给前端
        return R.ok().data("list", list);
    }

    /**
     * @Description 逻辑删除
     * @Param id:
     * @Author LanYun
     * @Date 2022/2/27 21:34
     */
    @DeleteMapping("/{id}")
    public R deleteId(@PathVariable("id") long id) {
        scenicMapper.logicDeleteById(id);
        return R.ok();
    }

    /**
     * @Description 更新
     * @Param scenicEntity:
     * @Author LanYun
     * @Date 2022/2/27 21:34
     */
    @PutMapping("/updateScenic")
    public R updateId(@RequestBody ScenicEntity scenicEntity) {
        // 通过景点对象的ID更新数据
        scenicMapper.updateById(scenicEntity);
        return R.ok();
    }

    /**
     * @Description 上传图片到oss
     * @Param file:
     * @Author LanYun
     * @Date 2022/2/28 10:06
     */
    @PostMapping("/uploadImage")
    public R uploadImage(MultipartFile file) {
        System.out.println(file);
        String url = scenicDao.uploadImageToALOSS(file);
        return R.ok().data("url", url);
    }

//    ---------------------------------以下为微信小程序请求的接口------------------------------------------

    @GetMapping("/list")
    public R getList() {
        List wx_scenic_list = redisTemplate.opsForList().range("wx_scenic_list", 0, -1);
        if(wx_scenic_list!=null&&wx_scenic_list.size()!=0){
            return R.ok().data("list",wx_scenic_list);
        }
        //分页查询
        StdPagedList<ScenicEntity> list = scenicMapper.stdPagedEntity(new ScenicQuery()
                .selectAll().where.isDeleted().eq(0).end()
        );
        List<ScenicEntity> data = list.getData();
        redisTemplate.opsForList().leftPushAll("wx_scenic_list", data);
        return R.ok().data("list", data);
    }

    @PostMapping("/calculateRoutes")
    public R getRoutesFromList(@RequestBody MapQuery mapQuery) {

        //1 获取经纬度列表
        ArrayList<String> dislist = mapQuery.getDisList();
        //2 获取ID列表
        String[] idList = mapQuery.getIdList();
        String string = Arrays.toString(idList);
        System.out.println("string = " + string);
        List tmp = redisTemplate.opsForList().range(string, 0, -1);
        if (tmp.size()!=0&&tmp!=null){
            return R.ok().data("list",tmp);
        }
        //3 将经纬度转换成距离矩阵
        int length = dislist.size();
        int[][] disMat = new int[length][length];
        for (int i = 0; i < length; i++) {
            String s = dislist.get(i);
            for (int j = 0; j < length; j++) {
                String s1 = dislist.get(j);
                // 通过经纬度获取每个景点之间的距离
                disMat[i][j] = DistanceUtil.getDistance(s, s1);
            }
        }
        GA ga = new GA(disMat.length, 50, 1000, 0.9f, 0.5f);
        Long[] solve = ga.init(disMat, idList).solve();
        ArrayList<ScenicEntity> scenicEntities = new ArrayList<>();
        for (int i = 1; i < solve.length - 1; i++) {
            System.out.println(solve[i]);
            ScenicQuery scenicQuery = new ScenicQuery();
            scenicQuery.where().id().eq(solve[i]).end();
            ScenicEntity one = scenicMapper.findOne(scenicQuery);
            scenicEntities.add(one);
        }
        redisTemplate.opsForList().rightPushAll(string, scenicEntities);

        return R.ok().data("list", scenicEntities);
    }


}
